/*
 * Copyright (c) 2008, Xiong Yingfei, the University of Tokyo All rights
 * reserved.
 */
package ac.jp.u_tokyo.SyncLib.interactive;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import ac.jp.u_tokyo.SyncLib.EqualSync;
import ac.jp.u_tokyo.SyncLib.SetMember;
import ac.jp.u_tokyo.SyncLib.SwitchCombinator;
import ac.jp.u_tokyo.SyncLib.Sync;
import ac.jp.u_tokyo.SyncLib.SyncFactory;
import ac.jp.u_tokyo.SyncLib.SetMember.MemberTester;
import ac.jp.u_tokyo.SyncLib.dictionaries.InsertNewKeyDynamicGet;
import ac.jp.u_tokyo.SyncLib.dictionaries.KeyFactory;
import ac.jp.u_tokyo.SyncLib.dictionaries.MatchingDictMapCombinator;
import ac.jp.u_tokyo.SyncLib.dictionaries.MaxIntegerKeyFactory;
import ac.jp.u_tokyo.SyncLib.dictionaries.StaticGet;
import ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory;

public class EJBConsole extends Console
{

	private static class MyTraceMap extends HashMap<String, Object>
	{

		/**
		 * 
		 */
		private static final long serialVersionUID = 5199954825904301844L;

		@Override
		public Object put(String key, Object value)
		{
			if (!inInitialization
					&& (this == initialPEJB || this == initialNPEJB
							|| this == initialModule || this == initialEntityBean))
			{
				System.out.println("!!!!!!!!!!!!!!!!!!!!!modified!");
				throw new RuntimeException();
			}
			return super.put(key, value);
		}
	}

	private static boolean inInitialization = true;

	static final MyTraceMap initialPEJB = new MyTraceMap();

	static final MyTraceMap initialNPEJB = new MyTraceMap();

	static final MyTraceMap initialModule = new MyTraceMap();

	static final MyTraceMap initialEntityBean = new MyTraceMap();

	
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		try
		{
			TraceAspect._showTrace = true;
			Console.interactiveExec(EJBConsole.class);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	private static MatchingDictMapCombinator createSync()
	{
		initialPEJB.put("Module", 1);
		initialPEJB.put("Persistent", true);
		initialNPEJB.put("Module", 1);
		initialNPEJB.put("Persistent", false);
		final Map<Integer, Map<String, Object>> initialModules = new HashMap<Integer, Map<String, Object>>();
		initialModules.put(1, new HashMap<String, Object>());

		inInitialization = false;

		SyncFactory containmentGetModule = getContainmentGet(initialPEJB,
				initialModules, initialModule);

		final GraphCombinatorFactory persistentEJB = new GraphCombinatorFactory();
		persistentEJB.setParaVars("ejb", "entityBean", "modules");
		persistentEJB.setOtherVars("ejbName", "module", "moduleName",
				"persistent");
		persistentEJB.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new StaticGet<String>("Persistent", false);
			}

		}, "ejb", "persistent");
		persistentEJB.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new EqualSync<Boolean>(true);
			}

		}, "persistent");
		persistentEJB.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new StaticGet<String>("Name", true);
			}

		}, "ejb", "ejbName");
		persistentEJB.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new StaticGet<String>("Name", true);
			}

		}, "module", "moduleName");
		persistentEJB.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new StaticGet<String>("ModuleName", false);
			}

		}, "entityBean", "moduleName");
		persistentEJB.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new StaticGet<String>("EJBName", false);
			}

		}, "entityBean", "ejbName");
		persistentEJB.connectSync(containmentGetModule, "ejb", "modules",
				"module");

		final GraphCombinatorFactory nonPersistentEJB = new GraphCombinatorFactory();
		nonPersistentEJB.setParaVars("ejb", "entityBean", "modules");
		nonPersistentEJB.setOtherVars("module", "persistent");
		nonPersistentEJB.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new EqualSync<Boolean>(false);
			}

		}, "persistent");
		nonPersistentEJB.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new StaticGet<String>("Persistent", false);
			}

		}, "ejb", "persistent");
		nonPersistentEJB.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new EqualSync<Map<String, Object>>(null);
			}

		}, "entityBean");
		nonPersistentEJB.connectSync(getContainmentGet(initialNPEJB,
				initialModules, initialModule), "ejb", "modules", "module");

		final GraphCombinatorFactory deletion = new GraphCombinatorFactory();
		deletion.setParaVars("ejb", "entityBean", "modules");
		deletion.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new EqualSync<Map<String, Object>>(null);
			}

		}, "ejb");
		deletion.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new EqualSync<Map<String, Object>>(null);
			}

		}, "entityBean");

		final SyncFactory switchSync = new SyncFactory() {

			public Sync create()
			{
				return new SwitchCombinator(new Sync[] {
						persistentEJB.create(), nonPersistentEJB.create(),
						deletion.create() });
			}

		};

		MatchingDictMapCombinator sync = new MatchingDictMapCombinator(
				switchSync, new KeyFactory[] { new MaxIntegerKeyFactory(),
						new MaxIntegerKeyFactory() }, 1);
		return sync;
	}

	private static SyncFactory getContainmentGet(
			final Map<String, Object> initialPEJB,
			final Map<Integer, Map<String, Object>> initialModules,
			final Map<String, Object> initialModule)
	{
		final GraphCombinatorFactory getModule = new GraphCombinatorFactory();
		getModule.setParaVars("ejb", "modules", "module");
		getModule.setOtherVars("moduleRef");
		getModule.connectSync(new SyncFactory() {

			public Sync create()
			{
				StaticGet<String> staticGet = new StaticGet<String>("Module",
						true);
				return staticGet;
			}

		}, "ejb", "moduleRef");
		getModule.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new InsertNewKeyDynamicGet<Integer>(true,
						new MaxIntegerKeyFactory());
			}

		}, "moduleRef", "modules", "module");
		getModule.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new SetMember<Map<String, Object>>(
						new MemberTester<Map<String, Object>>() {

							public boolean isMember(Map<String, Object> v)
							{
								return v != null;
							}

						}, initialModule);
			}

		}, "module");

		final GraphCombinatorFactory ejbNull = new GraphCombinatorFactory();
		ejbNull.setParaVars("ejb", "modules", "module");
		ejbNull.connectSync(new SyncFactory() {

			public Sync create()
			{
				return new EqualSync(null);
			}

		}, "ejb");

		SyncFactory containmentGetModule = new SyncFactory() {

			public Sync create()
			{
				return new SwitchCombinator(new Sync[] { getModule.create(),
						ejbNull.create() });
			}

		};
		return containmentGetModule;
	}

	///////////////////////////////////////////////////////////////////////////////////
	//generated code


	public static ac.jp.u_tokyo.SyncLib.SyncFactory getEqualFactory(Object value){
	ac.jp.u_tokyo.SyncLib.language.factories.EqualFactory var1 = new ac.jp.u_tokyo.SyncLib.language.factories.EqualFactory();
	var1.setValue(value);

	return var1;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getModulesAndNamesFactory(){
	ac.jp.u_tokyo.SyncLib.language.factories.SwitchCombinatorFactory var3 = new ac.jp.u_tokyo.SyncLib.language.factories.SwitchCombinatorFactory();
	ac.jp.u_tokyo.SyncLib.SyncFactory var4 = getSGetFactory("Name", true);
	var3.addFactory(var4);
	ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory var5 = new ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory();
	var5.setParaVars("a", "b");
	var5.setOtherVars();
	ac.jp.u_tokyo.SyncLib.SyncFactory var6 = getEqualFactory(null);
	var5.connectSync(var6, "a");
	ac.jp.u_tokyo.SyncLib.SyncFactory var7 = getEqualFactory(null);
	var5.connectSync(var7, "b");
	var3.addFactory(var5);
	ac.jp.u_tokyo.SyncLib.language.factories.EDictMapCombinatorFactory var2 = new ac.jp.u_tokyo.SyncLib.language.factories.EDictMapCombinatorFactory(var3, 2,0);

	return var2;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getPersistentFactory(){
	ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory var8 = new ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory();
	var8.setParaVars("ejb", "entitybean", "modules");
	var8.setOtherVars("moduleRef", "ejbName", "moduleName", "persistent");
	ac.jp.u_tokyo.SyncLib.SyncFactory var9 = getSGetFactory("Persistent", false);
	var8.connectSync(var9, "ejb", "persistent");
	ac.jp.u_tokyo.SyncLib.SyncFactory var10 = getEqualFactory(true);
	var8.connectSync(var10, "persistent");
	ac.jp.u_tokyo.SyncLib.SyncFactory var11 = getSGetFactory("Name", true);
	var8.connectSync(var11, "ejb", "ejbName");
	ac.jp.u_tokyo.SyncLib.SyncFactory var12 = getSGetFactory("EJBName", false);
	var8.connectSync(var12, "entitybean", "ejbName");
	ac.jp.u_tokyo.SyncLib.SyncFactory var13 = getSGetFactory("ModuleName", false);
	var8.connectSync(var13, "entitybean", "moduleName");
	ac.jp.u_tokyo.SyncLib.SyncFactory var14 = getSGetFactory("Module", true);
	var8.connectSync(var14, "ejb", "moduleRef");
	ac.jp.u_tokyo.SyncLib.SyncFactory var15 = getDGetFactory(true, true, (new ac.jp.u_tokyo.SyncLib.dictionaries.MaxIntegerKeyFactory()));
	var8.connectSync(var15, "moduleRef", "modules", "moduleName");

	return var8;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getMainFactory(){
	ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory var16 = new ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory();
	var16.setParaVars("ejbs", "modules", "entitybeans");
	var16.setOtherVars("modulenames");
	ac.jp.u_tokyo.SyncLib.SyncFactory var17 = getModulesAndNamesFactory();
	var16.connectSync(var17, "modules", "modulenames");
	ac.jp.u_tokyo.SyncLib.SyncFactory var18 = getContainmentReferenceMaintainerFactory("Module");
	var16.connectSync(var18, "ejbs", "modules");
	ac.jp.u_tokyo.SyncLib.SyncFactory var19 = getTwoViewMaintainerFactory();
	var16.connectSync(var19, "ejbs", "entitybeans", "modulenames");

	return var16;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getNotNullFactory(Object defaultValue){
	ac.jp.u_tokyo.SyncLib.SyncFactory var20 = getSetMemberFactory(defaultValue, (new ac.jp.u_tokyo.SyncLib.language.factories.NotNullTester()));

	return var20;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getContainmentReferenceMaintainerFactory(Object attribute){
	ac.jp.u_tokyo.SyncLib.SyncFactory var22 = getContainmentReferenceFactory(attribute);
	ac.jp.u_tokyo.SyncLib.language.factories.EDictMapCombinatorFactory var21 = new ac.jp.u_tokyo.SyncLib.language.factories.EDictMapCombinatorFactory(var22, 1,1);

	return var21;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getDeletionFactory(){
	ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory var23 = new ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory();
	var23.setParaVars("ejb", "entitybean", "modules");
	var23.setOtherVars();
	ac.jp.u_tokyo.SyncLib.SyncFactory var24 = getEqualFactory(null);
	var23.connectSync(var24, "ejb");
	ac.jp.u_tokyo.SyncLib.SyncFactory var25 = getEqualFactory(null);
	var23.connectSync(var25, "entitybean");

	return var23;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getSetMemberFactory(Object defaultValue, Object tester){
	ac.jp.u_tokyo.SyncLib.language.factories.SetMemberFactory var26 = new ac.jp.u_tokyo.SyncLib.language.factories.SetMemberFactory();
	var26.setDefaultValue(defaultValue);
	var26.setTester(tester);

	return var26;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getNonPersistentFactory(){
	ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory var27 = new ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory();
	var27.setParaVars("ejb", "entitybean", "modules");
	var27.setOtherVars("persistent");
	ac.jp.u_tokyo.SyncLib.SyncFactory var28 = getSGetFactory("Persistent", false);
	var27.connectSync(var28, "ejb", "persistent");
	ac.jp.u_tokyo.SyncLib.SyncFactory var29 = getEqualFactory(false);
	var27.connectSync(var29, "persistent");
	ac.jp.u_tokyo.SyncLib.SyncFactory var30 = getEqualFactory(null);
	var27.connectSync(var30, "entitybean");

	return var27;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getContainmentReferenceFactory(Object attribute){
	ac.jp.u_tokyo.SyncLib.language.factories.SwitchCombinatorFactory var31 = new ac.jp.u_tokyo.SyncLib.language.factories.SwitchCombinatorFactory();
	ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory var32 = new ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory();
	var32.setParaVars("srcObj", "tgtDict");
	var32.setOtherVars("tgtObj", "ref");
	ac.jp.u_tokyo.SyncLib.SyncFactory var33 = getSGetFactory(attribute, true);
	var32.connectSync(var33, "srcObj", "ref");
	ac.jp.u_tokyo.SyncLib.SyncFactory var34 = getDGetFactory(true, false, (new ac.jp.u_tokyo.SyncLib.dictionaries.MaxIntegerKeyFactory()));
	var32.connectSync(var34, "ref", "tgtDict", "tgtObj");
	ac.jp.u_tokyo.SyncLib.SyncFactory var35 = getNotNullFactory(0);
	var32.connectSync(var35, "tgtObj");
	var31.addFactory(var32);
	ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory var36 = new ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory();
	var36.setParaVars("srcObj", "tgtDict");
	var36.setOtherVars();
	ac.jp.u_tokyo.SyncLib.SyncFactory var37 = getEqualFactory(null);
	var36.connectSync(var37, "srcObj");
	var31.addFactory(var36);

	return var31;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getFindByFactory(Object attribute, Object keyFactory, Object dictOverVal){
	ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory var38 = new ac.jp.u_tokyo.SyncLib.graphCombinator.GraphCombinatorFactory();
	var38.setParaVars("d", "v", "k");
	var38.setOtherVars("d0");
	ac.jp.u_tokyo.SyncLib.SyncFactory var40 = getSGetFactory(attribute, true);
	ac.jp.u_tokyo.SyncLib.language.factories.EDictMapCombinatorFactory var39 = new ac.jp.u_tokyo.SyncLib.language.factories.EDictMapCombinatorFactory(var40, 2,0);
	var38.connectSync(var39, "d", "d0");
	ac.jp.u_tokyo.SyncLib.SyncFactory var41 = getDGetFactory(dictOverVal, true, keyFactory);
	var38.connectSync(var41, "k", "d0", "v");

	return var38;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getDGetFactory(Object dictOverValue, Object changeKeyFirst, Object keyFactory){
	ac.jp.u_tokyo.SyncLib.language.factories.DGetFactory var42 = new ac.jp.u_tokyo.SyncLib.language.factories.DGetFactory();
	var42.setDictOverValue(dictOverValue);
	var42.setChangeKeyFirst(changeKeyFirst);
	var42.setKeyFactory(keyFactory);

	return var42;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getTwoViewMaintainerFactory(){
	ac.jp.u_tokyo.SyncLib.language.factories.SwitchCombinatorFactory var44 = new ac.jp.u_tokyo.SyncLib.language.factories.SwitchCombinatorFactory();
	ac.jp.u_tokyo.SyncLib.SyncFactory var45 = getPersistentFactory();
	var44.addFactory(var45);
	ac.jp.u_tokyo.SyncLib.SyncFactory var46 = getNonPersistentFactory();
	var44.addFactory(var46);
	ac.jp.u_tokyo.SyncLib.SyncFactory var47 = getDeletionFactory();
	var44.addFactory(var47);
	ac.jp.u_tokyo.SyncLib.language.factories.DictMapCombinatorFactory var43 = new ac.jp.u_tokyo.SyncLib.language.factories.DictMapCombinatorFactory( new ac.jp.u_tokyo.SyncLib.dictionaries.KeyFactory[]{(new ac.jp.u_tokyo.SyncLib.dictionaries.MaxIntegerKeyFactory()), (new ac.jp.u_tokyo.SyncLib.dictionaries.MaxIntegerKeyFactory()), }, var44,1);

	return var43;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getIdFactory(){
	ac.jp.u_tokyo.SyncLib.language.factories.IDFactory var48 = new ac.jp.u_tokyo.SyncLib.language.factories.IDFactory();
	var48.setV1OverV2(true);

	return var48;
	}

	public static ac.jp.u_tokyo.SyncLib.SyncFactory getSGetFactory(Object key, Object dictOverValue){
	ac.jp.u_tokyo.SyncLib.language.factories.StaticGetFactory var49 = new ac.jp.u_tokyo.SyncLib.language.factories.StaticGetFactory();
	var49.setDictOverValue(dictOverValue);
	var49.setKey(key);

	return var49;
	}
}
